package org.weso.desempleo.model;

import org.weso.desempleo.services.to.ListMunicipalityStatsTO;
import org.weso.desempleo.to.MunicipalityStatsTO;

import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;

public class ChargerMunicipio extends Charger<ListMunicipalityStatsTO, 
MunicipalityStatsTO> {

	private final String DATASET = "Desempleo en España por municipios, " +
			"y edades";
	private ListMunicipalityStatsTO municipalities;
	
	public ChargerMunicipio() {
		municipalities = new ListMunicipalityStatsTO();
	}
	
	@Override
	public ListMunicipalityStatsTO obtain(String lang, String anyo,
			String month, String selector, String langAnt) {
		String query = prepareSparqlQuery(anyo, selector, month, lang);
		QueryExecution qExec = initializeQuery("http://localhost:8890/sparql",
				query);
		ListMunicipalityStatsTO municipios = (ListMunicipalityStatsTO)
				processResult(qExec.execSelect());
		return municipios;
	}

	private int findMunicipality(String municipality, String province) {
		int size = municipalities.getMunicipalities().size();
		for(int i = 0; i < size; i++) {
			MunicipalityStatsTO mun = municipalities.getMunicipalities().get(i);
			if(mun.getMunicipality().equals(municipality) && 
					mun.getProvince().equals(province)) {
				return i;
			}
		}
		return -1;
	}
	
	@Override
	public ListMunicipalityStatsTO processResult(ResultSet result) {
		int observaciones = 1;
		while(result.hasNext()) {
			QuerySolution sol = result.next();
			extractData(sol, observaciones);
			observaciones++;
		}
		return municipalities;
	}
	
	@Override
	public MunicipalityStatsTO extractData(QuerySolution sol, int observaciones) {
		String municipality = sol.get("mun").toString();
		String prov = sol.get("prov").toString();
		String period = sol.get("period").toString();
		String age = sol.getLiteral("edad").toString();
		age = age.substring(0, age.lastIndexOf('@'));
		String aux = sol.get("unemployment").toString();
		int unemployment = 0;
		if(isNumeric(aux)) {
			unemployment = Integer.parseInt(aux.substring(0, aux.indexOf('.')));
		}
		int pos = findMunicipality(municipality, prov);
		MunicipalityStatsTO muni = null;
		if(pos == -1) {		
			double population = Double.valueOf(sol.getLiteral("population").toString());
			double area = Double.valueOf(sol.getLiteral("area").toString());
			muni = new MunicipalityStatsTO(municipality, prov, population, 
					municipality, DATASET,  area);
			municipalities.add(muni);
		}else {
			muni = municipalities.getMunicipalities().get(pos);
		}
		muni.addUnemployment(unemployment, period, age);
		return muni;
	}

	private boolean isNumeric(String aux) {
		try {
			Double.valueOf(aux);
			return true;
		} catch(NumberFormatException e) {
			return false;
		}
	}

	@Override
	public String prepareSparqlQuery(String anyo, String selector,
			String month, String lang) {
		String query = "PREFIX o: <http://purl.org/weso/observatory/definitions/>\n";
		query += "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n";
		query += "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n";
		query += "SELECT ?mun ?prov ?period ?edad ?sexo ?unemployment" +
				" ?population ?area ?period\n";
		query += "FROM <http://purl.org/weso/observatory/observatoryByMunicipalities/>\n";
		query += "FROM <http://purl.org/weso/desempleo/resources/municipalities/>\n";
		query += "WHERE {\n";
		query += "\t?x rdf:type <http://purl.org/linked-data/cube#Observation>.\n";
		query += "\t?y rdf:type <http://purl.org/weso/observatory/definitions/Municipality> .\n";
		query += "\t?x o:refCouncil ?y .\n";
		query += "\t?y o:population ?population .\n";
		query += "\t?y o:area ?area .\n";
		query += "\t?y o:refMunicipality ?mun .\n";
		query += "\t?y o:community ?prov .\n";
		query += "\t?x o:refPeriod ?period .\n";
		query += "\t?x o:refAges ?edad .\n";
		query += "\t?x o:refGender ?sexo .\n";
		query += "\t?x o:unemployment ?unemployment .\n";
		query += "\tFILTER (langMatches(lang(?edad), \"" + lang + "\")) .\n";
		query += "\tFILTER (langMatches(lang(?sexo), \"" + lang + "\")) .\n";
		query += "\tFILTER (str(?period) = \"09-2011\" || str(?period) = \"09-2010\")";
		query += "\tFILTER (xsd:double(?population) > xsd:double(25000.0))";
		query += "}";
		//query += "LIMIT 100";
		return query;
	}

}
